{$E+}
{$E ERR1.TEXT}
{------------------------------------------------------------------------------------------------------------}
{					     UUniversalText V0.3					     }
{------------------------------------------------------------------------------------------------------------}
{$SETC ForOS := TRUE }
{$DECL WithUObject}
{$SETC WithUObject := TRUE}		   {Note: TRUE/FALSE status MUST agree with below}



UNIT {$IFC WithUObject}
     UTKUniversalText
     {$ELSEC}
     UUniversalText
     {$ENDC};

{$DECL IsIntrinsic}
{$SETC IsIntrinsic := TRUE}

{$SETC WithUObject := TRUE}		   {Note: TRUE/FALSE status MUST agree with above}

{$IFC IsIntrinsic}
INTRINSIC;
{$ENDC}

{$IFC NOT WithUObject}
    {$SETC LibraryVersion := 30 } { 10 = 1.0 libraries; 13 = 1.3 libraries; 20 = Pepsi, 30 = Spring, etc. }
{$ENDC}

INTERFACE

USES
{$IFC WithUObject}
    {$U libtk/UObject}	        UObject,
    {$SETC fTrce := fTrace}
{$ENDC}
    {$U libsm/UnitStd.obj }     UnitStd,
    {$U libsm/UnitHz.obj }      UnitHz,
{$IFC NOT WithUObject}
    {$U libpl/UClascal}		      UClascal,		      {Will be in PASLIB in Spring}
    {$U libqd/Storage.obj }     Storage,
{$ENDC}
{$IFC LibraryVersion <= 20}
    {$U libfm/FontMgr.obj }     FontMgr,
    {$U libqd/QuickDraw.obj }   QuickDraw,
{$ELSEC}
    {$U libqd/QuickDraw.obj }   QuickDraw,
    {$U libfm/FontMgr.obj }     FontMgr,
{$ENDC}
    {$U -#BOOT-SysCall }     Syscall,
    {$U libpm/PMDecl.obj }      PMDecl,
    {$U libpr/PrStdInfo.obj }   PrStdInfo,
    {$U libsu/UnitFmt.obj }     UnitFmt,
    {$U libsu/UnitCS.obj }      UnitCS,
    {$U libwm/Events.obj }      Events,
    {$U libsu/Scrap.obj }       Scrap;

{$DECL fUniversalTextTrace}

{$IFC NOT WithUObject}
    {$DECL fDebugMethods}
    {$SETC fDebugMethods := FALSE}	    {Must be FALSE}

    {$DECL fDbgObject}

    {$DECL fTrce}
    {$SETC fTrce := FALSE}		   {Must be FALSE}

    {$SETC fDbgObject := FALSE}		    {Set to FALSE for final libraries}
{$ENDC}


{$SETC fUniversalTextTrace := fTrce}	    {Normal}

{$DECL PasteTrace}			    {Generates READLN asking for tracing during Write UT}
{$SETC PasteTrace := FALSE}


TYPE

{$IFC NOT WithUObject}

    S255 =  STRING[255];
    THeap = Ptr;    {alias for THz}
    TClass = Ptr;   {alias for TPSliceTable in UClascal}

    TCollecHeader =  RECORD
        classPtr:       TClass;
        size:	        LONGINT;    {number of real elements, not counting the hole}
        dynStart:       INTEGER;    {bytes from the class ptr to the dynamic data; MAXINT if none allowed}
        holeStart:      INTEGER;    {0 = at the beginning, size = at the end; MAXINT = none allowed}
        holeSize:       INTEGER;    {measured in MemberBytes units}
        holeStd:        INTEGER;    {if the holeSize goes to 0, how much to grow the collection by}
        END;

    TFastString = RECORD	    {only access ch[i] when hole is at end & TString is not subclassed}
        header:	        TCollecHeader;
        ch:	        PACKED ARRAY[1..32740] OF CHAR;
        END;
    TPFastString = ^TFastString;
    THFastString = ^TPFastString;


    TUTObject = SUBCLASS OF NIL

        FUNCTION  {TUTObject.}CREATE(heap: THeap): TUTObject; ABSTRACT;
        FUNCTION  {TUTObject.}Heap: THeap;			        {which heap it is in}
        PROCEDURE {TUTObject.}FreeObject; DEFAULT;		        {frees just the object, not its contents}
        PROCEDURE {TUTObject.}Free; DEFAULT;			        {frees the object and its contents}
        FUNCTION  {TUTObject.}Class: TClass;
        END;

    TUTCollection = SUBCLASS OF TUTObject

      {Variables}
        size:	        LONGINT;    {number of real elements, not counting the hole}
        dynStart:       INTEGER;    {bytes from the class ptr to the dynamic data}
        holeStart:      INTEGER;    {0 means hole at the beginning, size means hole at the end}
        holeSize:       INTEGER;    {measured in MemberBytes units}
        holeStd:        INTEGER;    {if the holeSize goes to 0, how much to grow the collection by}

        FUNCTION  {TCollection.}CREATE(object: TUTObject; heap: THeap; initialSlack: INTEGER): TUTCollection;
        FUNCTION  {TCollection.}AddrMember(i: LONGINT): LONGINT;
        FUNCTION  {TCollection.}MemberBytes: INTEGER; ABSTRACT;
        PROCEDURE {TCollection.}EditAt(atIndex: LONGINT; deltaMembers: INTEGER);
        PROCEDURE {TCollection.}InsManyAt(i: LONGINT; otherCollection: TUTCollection; index, howMany: LONGINT);
        PROCEDURE {TCollection.}ResizeColl(membersPlusHole: INTEGER);
        PROCEDURE {TCollection.}ShiftColl(afterSrcIndex, afterDstIndex, howMany: INTEGER);
        PROCEDURE {TCollection.}StartEdit(withSlack: INTEGER);
        PROCEDURE {TCollection.}StopEdit;
        END;

    TUTArray = SUBCLASS OF TUTCollection

        recordBytes: INTEGER;

        FUNCTION  {TArray.}CREATE(object: TUTObject; heap: THeap; initialSlack, bytesPerRecord: INTEGER)
                                    : TUTArray;
        FUNCTION  {TArray.}MemberBytes: INTEGER; OVERRIDE;
        FUNCTION  {TArray.}At(i: LONGINT): Ptr; DEFAULT;
        PROCEDURE {TArray.}InsAt(i: LONGINT; pRecord: Ptr); DEFAULT;
        PROCEDURE {TArray.}InsLast(pRecord: Ptr);
        PROCEDURE {TArray.}DelAll;
        PROCEDURE {TArray.}DelAt(i: LONGINT); DEFAULT;
        PROCEDURE {TArray.}DelManyAt(i, howMany: LONGINT); DEFAULT;
        PROCEDURE {TArray.}PutAt(i: LONGINT; pRecord: Ptr);
        END;


    TUTString = SUBCLASS OF TUTCollection

        FUNCTION  {TString.}CREATE(object: TUTObject; heap: THeap; initialSlack: INTEGER): TUTString;
        FUNCTION  {TString.}At(i: LONGINT): CHAR;
        FUNCTION  {TString.}MemberBytes: INTEGER; OVERRIDE;
        PROCEDURE {TString.}ToPAOCAt(i, howMany: LONGINT; pPackedArrayOfCharacter: Ptr);
        PROCEDURE {TString.}InsAt(i: LONGINT; character: CHAR);
        PROCEDURE {TString.}InsPAOCAt(i: LONGINT; pPackedArrayOfCharacter: Ptr; howMany: LONGINT);
        PROCEDURE {TString.}DelAt(i: LONGINT);
        PROCEDURE {TString.}DelManyAt(i, howMany: LONGINT);
        PROCEDURE {TString.}DelAll;
        END;

{$ENDC}

    TEnumLevelOfGranularity = (UTCharacters, UTParagraphs);
    TLevelOfGranularity = SET OF TEnumLevelOfGranularity;

    TCharDescriptor = RECORD	  { character descroptor record }
            font:	    INTEGER;	    { font number }
            face:	    {$IFC LibraryVersion <= 20}TSeteface{$ELSEC}style{$ENDC};	       { formating }
            superscript:    -128..127;	    { number of bits to superscript }
            keepOnSamePage: BOOLEAN;
            END;

    TTabTypes   = (qLeftTab,    qCenterTab,     qRightTab,      qPeriodTab,     qCommaTab);
    TTabFill    = (tNoFill,     tDotFill,       tHyphenFill,    tUnderLineFill);
    TParaTypes  = (qLeftPara,   qCenterPara,    qRightPara,     qJustPara);

    TTabDescriptor = RECORD
            position:	        INTEGER;	    {Location of the tab}
            fillBetweenTabs:    TTabFill;	    {Fill character for the tab}
            tabType:	        TTabTypes;	    {Type of tab}
            END;

    TParaDescriptor = RECORD
            paragraphStart:     BOOLEAN;  { TRUE if the beginning of the run is also the beginning of a paragraph}
{$IFC WithUObject}
            additionalChrInParagraph:   INTEGER;
{$ENDC}
            firstLineMargin:    INTEGER;	    {Left margin of first line}
            bodyMargin:	        INTEGER;	    {Left margin of subsequent lines}
            rightMargin:        INTEGER;	    {Right margin}
            paraLeading:        INTEGER;	    {Paragraph leading}
            lineSpacing:        0..63;		    {Inter-line spacing }
{$IFC WithUObject}
            tabTable:	        TArray {OF TTabDescriptor}; { table of tabs  }
{$ELSEC}
            tabTable:	        TUTArray {OF TTabDescriptor}; { table of tabs  }
{$ENDC}
            paraType:	        TParaTypes;	    {Paragraph adjustment }
            hasPicture:	        BOOLEAN;	    {Is there a picture avaible for this paragraph?}
            END;


{$IFC WithUObject}
    TTKUnivText = SUBCLASS OF TOBJECT
{$ELSEC}
    TUnivText   = SUBCLASS OF TUTObject
{$ENDC}
        paragraphDescriptor:    TParaDescriptor;
        characterDescriptor:    TCharDescriptor;
        maxDataSize:	        INTEGER;
{$IFC WithUObject}
        data:		        TString;
{$ELSEC}
        data:		        TUTString;
{$ENDC}
        itsOurTString:	        BOOLEAN;

{$IFC WithUObject}
        FUNCTION  {TTKUnivText.}CREATE(object: TObject;
                                     itsHeap: THeap;
                                     itsTString: TString;
                                     itsDataSize: INTEGER) : TTKUnivText;
{$ELSEC}
        FUNCTION  {TUnivText.}CREATE(object: TUTObject;
                                     itsHeap: THeap;
                                     itsTString: TUTString;
                                     itsDataSize: INTEGER) : TUnivText;
{$ENDC}
        PROCEDURE {TUnivText.}Free; OVERRIDE;
        PROCEDURE {TUnivText.}RunToStream;
        PROCEDURE {TUnivText.}StreamToTRun;
        PROCEDURE {TUnivText.}TabTableToArgTbd;
        PROCEDURE {TUnivText.}ArgTbdToTabTable;
        END;


{$IFC WithUObject}
    TTKReadUnivText = SUBCLASS OF TTKUnivText
{$ELSEC}
    TReadUnivText   = SUBCLASS OF TUnivText
{$ENDC}

{$IFC WithUObject}
        buffer:	        TString;
{$ELSEC}
        buffer:	        TUTString;
{$ENDC}
        columnCount:    INTEGER;
        dataBeforeTab:  BOOLEAN;

{$IFC WithUObject}
        FUNCTION  {TReadUnivText.}CREATE(object: TObject;
                                         itsHeap: THeap;
                                         itsTString: TString;
                                         itsDataSize: INTEGER;
                                         LevelOfGranularity: TLevelOfGranularity)
                                                                                 : TTKReadUnivText;
{$ELSEC}
        FUNCTION  {TReadUnivText.}CREATE(object: TUTObject;
                                         itsHeap: THeap;
                                         itsTString: TUTString;
                                         itsDataSize: INTEGER;
                                         LevelOfGranularity: TLevelOfGranularity)
                                                                                 : TReadUnivText;
{$ENDC}

        PROCEDURE {TReadUnivText.}Free; OVERRIDE;
        PROCEDURE {TReadUnivText.}ReadRun;	  { Returns one run of text each time called }
        PROCEDURE {TReadUnivText.}Restart;	  { Resets the object to read from the begining }

        PROCEDURE {TReadUnivText.}ScanTable(VAR rows,
                                                tabColumns,
                                                tabStopColumns: INTEGER);
                                    { Returns number of rows and colums of scrap if a valid table }

        FUNCTION  {TReadUnivText.}ReadField(    maxFieldSize: INTEGER;
                                            VAR fieldOverflow: BOOLEAN;
                                            VAR fieldTerminator: CHAR;
                                            VAR tabType: TTabTypes)
                                                                   : BOOLEAN;
                                                { Returns one field of text each time called }

        FUNCTION  {TReadUnivText.}ReadLine(    maxLineSize: INTEGER;
                                           VAR lineOverflow: BOOLEAN;
                                           VAR lineTerminator: CHAR)
                                                                    : BOOLEAN;
                                                { Returns one line of text each time called }
        FUNCTION  {TReadUnivText.}GetParaPicture(heap: THeap)
                                                                    : PicHandle;
                                                { Copies the picture for the current paragraph into heap }
        END;


{$IFC WithUObject}
    TTKWriteUnivText = SUBCLASS OF TTKUnivText
{$ELSEC}
    TWriteUnivText   = SUBCLASS OF TUnivText
{$ENDC}

{$IFC WithUObject}
        FUNCTION  {TWriteUnivText.}CREATE(object: TObject;
                                          itsHeap: THeap;
                                          itsTString: TString;
                                          itsDataSize: INTEGER)
                                                               : TTKWriteUnivText;
{$ELSEC}
        FUNCTION  {TWriteUnivText.}CREATE(object: TUTObject;
                                          itsHeap: THeap;
                                          itsTString: TUTString;
                                          itsDataSize: INTEGER)
                                                               : TWriteUnivText;
{$ENDC}
        PROCEDURE {TWriteUnivText.}FillParagraph;       {Writes one run of text each time called}
        END;

{$IFC NOT WithUObject}
    FUNCTION  NewUTObject(heap: THeap; itsClass: TClass): TUTObject;
{$ENDC}

{$IFC fUniversalTextTrace}
VAR
    fPrintSecrets:  BOOLEAN;
{$ENDC}

IMPLEMENTATION

{$IFC fDbgOk}
{$R+}
{$ELSEC}
{$R-}
{$ENDC}

{$IFC fSymOk}
{$D+}
{$ELSEC}
{$D-}
{$ENDC}

{$SETC doTraceUT := FALSE}
{$SetC fTraceUT := doTraceUT AND fUniversalTextTrace}

{$IFC WithUObject}
{$S TKUTMain}
{$ELSEC}
{$S UTMain}
{$ENDC}

{$I libut/UUnivText2.text}

{$IFC WithUObject}
{$S TKUTInit}
{$ELSEC}
{$S UTInit}
{$ENDC}

END.
